From: Alex Williamson Date: Thu, 27 Sep 2007 21:12:58 +0000 (-0600) Subject: [IA64] Kexec: Add kexec_disable_iosapic X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14946 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=794dcb7321b1e5201a6eaf2e419fff243adb598c;p=xen.git [IA64] Kexec: Add kexec_disable_iosapic Ported from Linux, this shuts down iosapic before preforming kexec. This resolves a problem whereby the serial port on an HP RX2620 (which uses IOSAPIC) was not able to accept input. It probably resolves a bunch of other as yet unseen problems too. Thanks to Takebe-san for working out the solution to this puzzle. Cc: Akio Takebe Signed-off-by: Simon Horman --- diff --git a/xen/arch/ia64/linux-xen/iosapic.c b/xen/arch/ia64/linux-xen/iosapic.c index 90d9ba38f4..64cc108a6f 100644 --- a/xen/arch/ia64/linux-xen/iosapic.c +++ b/xen/arch/ia64/linux-xen/iosapic.c @@ -268,6 +268,24 @@ nop (unsigned int vector) /* do nothing... */ } +void +kexec_disable_iosapic(void) +{ + struct iosapic_intr_info *info; + struct iosapic_rte_info *rte; + u8 vec = 0; + for (info = iosapic_intr_info; info < + iosapic_intr_info + IA64_NUM_VECTORS; ++info, ++vec) { + list_for_each_entry(rte, &info->rtes, + rte_list) { + iosapic_write(rte->addr, + IOSAPIC_RTE_LOW(rte->rte_index), + IOSAPIC_MASK|vec); + iosapic_eoi(rte->addr, vec); + } + } +} + static void mask_irq (unsigned int irq) { diff --git a/xen/arch/ia64/xen/crash.c b/xen/arch/ia64/xen/crash.c index df340b1c57..1bdf36a5d1 100644 --- a/xen/arch/ia64/xen/crash.c +++ b/xen/arch/ia64/xen/crash.c @@ -30,6 +30,7 @@ void machine_crash_shutdown(void) dom0_mm_pgd_mfn = __pa(dom0->arch.mm.pgd) >> PAGE_SHIFT; memcpy((char *)info + offsetof(crash_xen_info_t, dom0_mm_pgd_mfn), &dom0_mm_pgd_mfn, sizeof(dom0_mm_pgd_mfn)); + kexec_disable_iosapic(); #ifdef CONFIG_SMP smp_send_stop(); #endif diff --git a/xen/arch/ia64/xen/machine_kexec.c b/xen/arch/ia64/xen/machine_kexec.c index 01acaa5ce7..5cf49f21f8 100644 --- a/xen/arch/ia64/xen/machine_kexec.c +++ b/xen/arch/ia64/xen/machine_kexec.c @@ -85,6 +85,7 @@ static void ia64_machine_kexec(struct unw_frame_info *info, void *arg) void machine_kexec(xen_kexec_image_t *image) { + kexec_disable_iosapic(); unw_init_running(ia64_machine_kexec, image); for(;;); } diff --git a/xen/include/xen/kexec.h b/xen/include/xen/kexec.h index 523846af06..1e04f9733c 100644 --- a/xen/include/xen/kexec.h +++ b/xen/include/xen/kexec.h @@ -27,6 +27,7 @@ void machine_kexec_reserved(xen_kexec_reserve_t *reservation); void machine_reboot_kexec(xen_kexec_image_t *image); void machine_kexec(xen_kexec_image_t *image); void kexec_crash(void); +void kexec_disable_iosapic(void); void kexec_crash_save_cpu(void); crash_xen_info_t *kexec_crash_save_info(void); void machine_crash_shutdown(void);